package 多线程;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @
 * @date 2025/06/29
 */
@Slf4j
public class 优雅的关闭线程池 {

    public static void main(String[] args) {

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                Runtime.getRuntime().availableProcessors() * 2,
                1L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100)) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {

                if (t != null) {
                    log.error(t.getMessage(), t);
                }
                if (t == null && r instanceof Future<?>) {
                    Future<?> future = (Future<?>) r;
                    if (future.isDone()) {
                        try {
                            future.get();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        } catch (ExecutionException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        };

    }

    /**
     * shutdown()：
     * 不会再接受新任务的提交
     * 在shutdown调用之前的任务会被执行下去
     * 待执行的任务和正在执行的任务都不会取消，将继续执行
     * 如果已经shutdown了，再调用不会有其他影响
     * shutdownNow()：
     * 不会再接受新任务的提交
     * 尝试停止所有正在执行的任务（但不保证一定停止，需要响应中断的任务才会被停止）
     * 待执行的任务会取消并返回等待队列的列表
     * 该方法返回是，这些等待的任务将从队列中清空
     * awaitTermination(long timeout, TimeUnit unit)：
     * 当等待超时设置的时间，检查线程池是否停止
     * 如果执行了返回true，如果还有未执行完成的任务，返回false，并解除阻塞
     */
    public static void findOK_shutdownAndAwaitTermination(ExecutorService executorService) {

        if (executorService != null && !executorService.isShutdown()) {
            try {

                executorService.shutdown();
                if (!executorService.awaitTermination(120, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();

                    if (!executorService.awaitTermination(120, TimeUnit.SECONDS)) {
                        System.out.println("Pool did not terminate");
                    }
                }

            } catch (InterruptedException ie) {

                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

}
